package com.acme.bankapp.service.bank;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.exceptions.InvalidFeed;

public class BankServer {
	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;

	void startServer(BankService bankService, Bank bank) {
		try {
			providerSocket = new ServerSocket(2004, 10);
			System.out.println("Waiting for connection");
			while (true) {
				try {
					connection = providerSocket.accept();
					System.out.println("Connection received from "
							+ connection.getInetAddress().getHostName());
					out = new ObjectOutputStream(connection.getOutputStream());
					out.flush();
					in = new ObjectInputStream(connection.getInputStream());
					sendMessage("Connection successful");
					boolean clientSaidGoodbye = false;
					do {
						try {
							message = (String) in.readObject();
							System.out.println("client>" + message);
							if (message.equals("bye")) {
								sendMessage("bye");
								clientSaidGoodbye = true;
							} else if (message.startsWith("add")) {
								try {
									bankService.addClient(bank,
													BankDataLoaderService.getClientFromFeedString(message.substring(3).trim()));
									sendMessage("client added");
								} catch (InvalidFeed e) {
									System.err.println("Bad feed string");
									sendMessage("Invalid feed string");
								}
							} else if (message.equals("stat")) {
								sendMessage(BankReport.getReport(bank));
							} else {
								sendMessage("Invalid command");
							}
						} catch (ClassNotFoundException | NullPointerException e) {
							System.err.println("Data received in unknown format");
							clientSaidGoodbye = true;
						}
					} while (!clientSaidGoodbye);
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						in.close();
						out.close();
						connection.close();
					} catch (IOException ioException) {
						ioException.printStackTrace();
					}

				}
			}
		} catch (IOException ioException) {
			ioException.printStackTrace();
		} finally {
			try {
				providerSocket.close();
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}

}
